package com.micro.frog.job.service.impl;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.micro.frog.core.annotations.ScheduleTask;
import com.micro.frog.core.common.PageResult;
import com.micro.frog.core.common.Result;
import com.micro.frog.core.contants.MaGlobal;
import com.micro.frog.core.exception.MaException;
import com.micro.frog.job.dao.JobMapper;
import com.micro.frog.job.model.dto.JobDTO;
import com.micro.frog.job.model.entity.Job;
import com.micro.frog.job.model.vo.TaskVO;
import com.micro.frog.job.service.JobLogService;
import com.micro.frog.job.service.JobService;
import com.micro.frog.job.utils.ScheduleUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @author :  ljh
 * @date : 2018/5/8
 **/
@Slf4j
@Service
public class JobServiceImpl implements JobService {

    @Autowired
    JobMapper jobMapper;
    @Autowired
    JobLogService logService;

    @Override
    public List<Job> all() {
        return jobMapper.selectByCondition(null);
    }

    @Override
    public PageResult listPage(JobDTO pageVO) {
        pageVO.init();
        Page page = PageHelper.startPage(pageVO.getPageNum(), pageVO.getPageSize(), true);
        List<Job> list = jobMapper.selectByCondition(pageVO);
        List<TaskVO> vos = new ArrayList<>();
        for (Job job : list) {
            TaskVO vo = new TaskVO();
            BeanUtils.copyProperties(job, vo);
            vo.setLatestLog(logService.selectLatest(job.getId()));
            vos.add(vo);
        }
        PageResult result = new PageResult();
        result.setCode(MaGlobal.SUCCESS);
        result.setTotal(page.getTotal());
        result.setData(vos);
        return result;
    }

    @Override
    public int add(Job job) {
        job.setIsDeleted("N");
        job.setCreatedTime(new Date());
        return jobMapper.insertSelective(job);
    }

    @Override
    public int delete(Integer id) {
        Job role = new Job();
        role.setId(id);
        role.setIsDeleted("Y");
        return jobMapper.updateByPrimaryKeySelective(role);
    }

    @Override
    public int update(Job job) {
        job.setUpdatedTime(new Date());
        return jobMapper.updateByPrimaryKeySelective(job);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result addTaskAndJob(Job job) throws MaException {
        Result result = Result.newResult();
        try {
            job.setIsDeleted("N");
            job.setCreatedTime(new Date());
            job.setUpdatedTime(new Date());
            if (StringUtils.isEmpty(job.getName())) {
                result.setFlag(false);
                result.setMsg("任务名称不能为空");
                return result;
            }
            ScheduleUtils.checkExist(job.getName());
            ScheduleUtils.createSchedule(job);
            jobMapper.insertSelective(job);
            result.setFlag(true);
            result.setMsg("修改成功");
            return result;
        } catch (MaException e) {
            result.setFlag(false);
            result.setMsg(e.getMessage());
            throw e;
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result updateTaskAndRebuildJob(Job job) throws Exception {
        Result result = Result.newResult();
        try {
            job.setUpdatedTime(new Date());
            ScheduleUtils.rescheduleJob(job);
            jobMapper.updateByPrimaryKeySelective(job);
            result.setFlag(true);
            result.setMsg("修改成功");
            return result;
        } catch (Exception e) {
            e.printStackTrace();
            throw e;
        }
    }

    @Override
    public Result runTask(Integer[] taskIds, String runner) throws Exception {
        if (null == taskIds || taskIds.length <= 0) {
            return Result.fail("请选择需要触发的任务");
        }
        for (int i = 0; i < taskIds.length; i++) {
            Job job = jobMapper.selectByPrimaryKey(taskIds[i]);
            Thread.sleep(30000);
            run(new Object[]{job});
        }
        return Result.ok("执行成功", runner);
    }

    @ScheduleTask
    private Result run(Object[] args) throws Exception {
        Job job = new Job();
        BeanUtils.copyProperties(args[0], job);
        if (null != job) {
            ScheduleUtils.runJob(job);
        }
        return Result.ok("处理成功");
    }
}
